package com.zhiwei.codesecurity.common.base;

import com.zhiwei.codesecurity.common.utils.DateUtils;
import com.zhiwei.codesecurity.entity.ScheduleJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;

public abstract class BaseJob implements Job {
    final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void before(ScheduleJob scheduleJob) {
        logger.info("========== Begin Task info.[jobName:{}, date:{}] ==============", scheduleJob.getJobName(),
                DateUtils.format(new Date()));
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
        ScheduleJob scheduleJob = (ScheduleJob) mergedJobDataMap.get(ScheduleJob.JOB_PARAM_KEY);

        try {
            this.before(scheduleJob);
            this.handeln(scheduleJob);
        } catch (Exception e) {
            this.error(scheduleJob, e);
        }

        this.after(scheduleJob);
    }

    public void after(ScheduleJob scheduleJob) {
        logger.info("========== End Task.[jobName:{}, date:{}] ==============", scheduleJob.getJobName(),
                DateUtils.format(new Date()));
    }

    public void error(ScheduleJob scheduleJob, Exception e) {
        logger.error("[jobName:{}], execute job err={}", scheduleJob.getJobName(), e);
    }

    /**
     * 任务处理流程
     * @param scheduleJob
     * @throws Exception
     */
    public abstract void handeln(ScheduleJob scheduleJob) throws Exception;

    /**
     * 定时任务并发执行判断
     *
     * @param context
     * @return true : 并发执行
     * @throws SchedulerException
     */
    protected synchronized boolean isConcurrentExecute(JobExecutionContext context) throws SchedulerException {
        int concurrent = 0;
        String currentJobName = context.getJobInstance().getClass().getName();
        List<JobExecutionContext> jobExecutionContexts = context.getScheduler().getCurrentlyExecutingJobs();
        for (JobExecutionContext jobExecutionContext : jobExecutionContexts) {
            String jobName = jobExecutionContext.getJobInstance().getClass().getName();
            if (currentJobName.equals(jobName)) {
                concurrent++;
            }
        }
        if (concurrent > 1) {
            return true;
        }
        return false;
    }
}
